package com.guigu.qingcheng.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.guigu.qingcheng.client.GoodsClient;
import com.guigu.qingcheng.client.WebPortalClient;
import com.guigu.qingcheng.config.RabbitConfig;
import com.guigu.qingcheng.excption.GuliException;
import com.guigu.qingcheng.mapper.*;
import com.guigu.qingcheng.pojo.*;
import com.guigu.qingcheng.pojo.dto.OrderItemSku;
import com.guigu.qingcheng.pojo.vo.CategoryReportVo;
import com.guigu.qingcheng.pojo.vo.CloseOrderVo;
import com.guigu.qingcheng.pojo.vo.OrderHeBinVo;
import com.guigu.qingcheng.service.TbOrderService;
import com.guigu.qingcheng.service.WxPayService;
import com.guigu.qingcheng.utils.IdWorker;
import com.guigu.qingcheng.utils.PageUtil;
import com.sun.org.apache.xml.internal.dtm.ref.sax2dtm.SAX2DTM2;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;


/**
*
* @author Jiang
* @date 2020/07/31
*/
@Service
public class TbOrderServiceImpl implements TbOrderService {
    @Autowired(required = false)
    private TbOrderMapper tbOrderMapper;

    @Autowired
    private IdWorker idWorker;

    @Autowired(required = false)
    private TbOrderLogMapper tbOrderLogMapper;

    @Autowired(required = false)
    private TbReturnOrderMapper tbReturnOrderMapper;

    @Autowired(required = false)
    private TbReturnOrderItemMapper tbReturnOrderItemMapper;

    @Autowired
    private WebPortalClient webPortalClient;

    @Autowired
    private GoodsClient goodsClient;


    @Autowired
    private AmqpTemplate amqpTemplate;

    @Override
    public List<Map> orders(CategoryReportVo categoryReportVo) {
        return tbOrderMapper.orders(categoryReportVo);
    }

    @Override
    public Map Queryorderstatus( Integer status) {
        return tbOrderMapper.Queryorderstatus(status);
    }

    @Override
    public Map findtodayOrder(LocalDate localDate) {
        return tbOrderMapper.findtodayOrder(localDate);
    }

    @Autowired(required = false)
    private TbOrderItemMapper tbOrderItemMapper;

    @Override
    public List<TbOrder> queryAll() {
        List<TbOrder> tbOrder = tbOrderMapper.selectAll();
            return tbOrder;
    }


    public  void addLog(TbOrder order,String beizhu){
        // 记录订单日志
        TbOrderLog log=new TbOrderLog();
        log.setId(idWorker.nextId()+""); // id
        log.setOperater("system"); // 操作员 暂时设为系统
        log.setOperateTime(new Date()); // 操作时间
        log.setOrderId(order.getId()); // 订单id
        log.setOrderStatus(order.getOrderStatus()); // 订单状态
        log.setPayStatus(order.getPayStatus()); // 付款状态
        log.setConsignStatus(order.getConsignStatus()); // 发货状态
        log.setRemarks(beizhu); // 备注
        tbOrderLogMapper.insertSelective(log);
    }

    @Override
    public PageUtil<TbOrder> findListAll(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        Page<TbOrder> pages = (Page<TbOrder>) tbOrderMapper.selectAll();
        PageUtil<TbOrder> pageUtil=new PageUtil<>();
        pageUtil.setRows(pages.getResult());
        pageUtil.setTotal(pages.getTotal());
        return pageUtil;
    }


    @Override
    public PageUtil<TbOrder> pageQueryByAll(Integer pageNum, Integer pageSize, TbOrder tbOrder) {

        Example example=new Example(TbOrder.class);
        Example.Criteria criteria = example.createCriteria();
        // TODO 待实现 重新实现判断参数

        // 订单编号
        if(!StringUtils.isEmpty(tbOrder.getId())){
            criteria.andEqualTo("id",tbOrder.getId());
        }
        //用户名
        if(!StringUtils.isEmpty(tbOrder.getUsername())){
            criteria.andLike("username","%"+tbOrder.getUsername()+"%");
        }
        // 收货人
        if(!StringUtils.isEmpty(tbOrder.getReceiverContact())){
           criteria.andEqualTo("receiverContact",tbOrder.getReceiverContact());
        }
        // 订单状态
        if(!StringUtils.isEmpty(tbOrder.getOrderStatus())){
            criteria.andEqualTo("orderStatus",tbOrder.getOrderStatus());
        }
        // 订单未删除
        criteria.andEqualTo("isDelete","0");

        // 订单来源
        if(!StringUtils.isEmpty(tbOrder.getSourceType())){
            criteria.andEqualTo("sourceType",tbOrder.getSourceType());
        }
        // 提交时间
        if(!StringUtils.isEmpty(tbOrder.getCreateTime())){
            criteria.andLessThanOrEqualTo("createTime",tbOrder.getCreateTime());
        }
        PageHelper.startPage(pageNum,pageSize);
        Page<TbOrder> pages = (Page<TbOrder>) tbOrderMapper.selectByExample(example);
        PageUtil<TbOrder> pageUtil=new PageUtil<>();
        pageUtil.setRows(pages.getResult());
        pageUtil.setTotal(pages.getTotal());
        return pageUtil;
     }


    @Override
    public boolean saveTbOrder(TbOrder tbOrder) {
        int insert = tbOrderMapper.insert(tbOrder);
        if(insert>0){
            return true;
        }
        return false;
    }

    @Override
    public boolean updateTbOrder(TbOrder tbOrder) {
        int i = tbOrderMapper.updateByPrimaryKeySelective(tbOrder);
        addLog(tbOrder,"修改订单收货人信息");
        if(i>0){
            return true;
        }
        return false;
    }


    @Transactional
    @Override
    public boolean deleteById(Integer id) {
        TbOrder order = tbOrderMapper.selectByPrimaryKey(id);
        order.setIsDelete("1");
        tbOrderMapper.updateByPrimaryKeySelective(order);
        addLog(order,"删除订单:"+order.getId());
        return true;
    }

    @Override
    public TbOrder findById(String id) {
        TbOrder tbOrder = tbOrderMapper.selectByPrimaryKey(id);
        return tbOrder;
    }

    @Override
    public List<TbOrder> pageQueryIdsByAll(String ids) {
        if(!StringUtils.isEmpty(ids)){
            String[] arr = ids.split(",");
            List<TbOrder> tbOrders = tbOrderMapper.pageQueryIdsByAll(arr);
            return tbOrders;
        }
        throw new GuliException(20001,"ids不能为空");
    }

    @Transactional
    @Override
    public void batchSend(List<TbOrder> tbOrders) {
        for(TbOrder order:tbOrders){
            if(StringUtils.isEmpty(order.getShippingCode()) || StringUtils.isEmpty(order.getShippingName())){
                throw new GuliException(20001,"请选择快递公司填写快递单号");
            }
        }

        // 循环修改发货状态
        for(TbOrder order:tbOrders){
            order.setOrderStatus("2"); // 订单状态   已发货
            order.setConsignStatus("1");// 发货状态   已发货
            order.setConsignTime(new Date()); // 发货时间
            tbOrderMapper.updateByPrimaryKeySelective(order);

            // 记录订单日志
            addLog(order,"订单发货:"+order.getId());
        }
    }


    @Transactional
    @Override
    public void heBin(OrderHeBinVo orderHeBinVo) {

        TbOrder zhudd = tbOrderMapper.selectByPrimaryKey(orderHeBinVo.getZhuDinDanId());
        TbOrder condd = tbOrderMapper.selectByPrimaryKey(orderHeBinVo.getConDinDanId());
        if(condd.getOrderStatus().equals("2") || condd.getOrderStatus().equals("3") || condd.getOrderStatus().equals("4")){
            throw new GuliException(20001,"该从订单已交易完成，合并失败");
        }
        // 将从订单的信息合并到主订单
        zhudd.setTotalNum(zhudd.getTotalNum()+condd.getTotalNum()); // 总数量
        zhudd.setTotalMoney(zhudd.getTotalMoney()+condd.getTotalMoney()); // 总金额
        zhudd.setPayMoney(zhudd.getPayMoney()+condd.getPayMoney()); // 实付金额
        zhudd.setUpdateTime(new Date()); // 订单更新时间

        tbOrderMapper.updateByPrimaryKeySelective(zhudd);
        // 从订单的订单明细也归属于主订单
        Example example=new Example(TbOrderItem.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("orderId",condd.getId());
        List<TbOrderItem> tbOrderItems = tbOrderItemMapper.selectByExample(example);
        for (TbOrderItem t : tbOrderItems) {
            t.setOrderId(zhudd.getId());
            tbOrderItemMapper.updateByPrimaryKeySelective(t);
        }
        // 对从订单进行逻辑删除
        condd.setIsDelete("1");
        tbOrderMapper.updateByPrimaryKeySelective(condd);

        // 记录订单日志
        addLog(condd,"订单合并 新订单号: "+zhudd.getId());
    }

    @Transactional
    @Override
    public void closeOrder(CloseOrderVo closeOrderVo) {
        // 订单状态改为关闭
        TbOrder order = tbOrderMapper.selectByPrimaryKey(closeOrderVo.getId());
        order.setOrderStatus("4");

        tbOrderMapper.updateByPrimaryKeySelective(order);

        // 记录订单日志
        addLog(order,"订单关闭 : "+closeOrderVo.getBeizhu());
    }

    @Transactional
    @Override
    public void quxiaoDD(TbReturnOrder tbReturnOrder) {
        // 查询订单数据
        TbOrder order = tbOrderMapper.selectByPrimaryKey(tbReturnOrder.getOrderId());
        // 查询订单明细数据
        Example example=new Example(TbOrderItem.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("orderId",tbReturnOrder.getOrderId());
        List<TbOrderItem> tbOrderItems = tbOrderItemMapper.selectByExample(example);

        // 封装订单退款数据
        tbReturnOrder.setId(idWorker.nextId()); // 服务单号
        tbReturnOrder.setApplyTime(new Date()); // 申请时间
        tbReturnOrder.setUserAccount(order.getUsername()); // 用户账号
        tbReturnOrder.setLinkman(order.getReceiverContact()); // 联系人
        tbReturnOrder.setLinkmanMobile(order.getReceiverMobile()); // 联系人手机
        tbReturnOrder.setType("2"); //类型 1.退货  2.退款
        tbReturnOrder.setStatus("0"); // 申请状态
        tbReturnOrder.setReturnCause(0);// 退货退款原因
        tbReturnOrderMapper.insert(tbReturnOrder);


        for (TbOrderItem item : tbOrderItems) {
            // 封装退款订单明细数据
            TbReturnOrderItem tbReturnOrderItem=new TbReturnOrderItem();
            tbReturnOrderItem.setId(idWorker.nextId());
            tbReturnOrderItem.setCategoryId(item.getCategoryId3().longValue()); //分类
            tbReturnOrderItem.setSpuId(Long.parseLong(item.getSpuId())); //
            tbReturnOrderItem.setSkuId(Long.parseLong(item.getSkuId()));
            tbReturnOrderItem.setOrderId(tbReturnOrder.getOrderId());
            tbReturnOrderItem.setOrderItemId(Long.parseLong(item.getId()));
            tbReturnOrderItem.setReturnOrderId(tbReturnOrder.getId());
            tbReturnOrderItem.setTitle(item.getName());
            tbReturnOrderItem.setPrice(item.getPrice());
            tbReturnOrderItem.setNum(item.getNum());
            tbReturnOrderItem.setMoney(item.getMoney());
            tbReturnOrderItem.setPayMoney(item.getPayMoney());
            tbReturnOrderItem.setImage(item.getImage());
            tbReturnOrderItem.setWeight(item.getWeight());
            tbReturnOrderItemMapper.insert(tbReturnOrderItem);

            // 修改订单明细退货状态为已申请
            item.setIsReturn("1");
            tbOrderItemMapper.updateByPrimaryKeySelective(item);
        }

        // 修改订单信息

        // TODO 订单没有标识列标志退款

        // 记录订单日志
        addLog(order,"订单退款："+tbReturnOrder.getDescription());
    }

    @Override
    public Map<String, Object> addTbOrder(TbOrder tbOrder) {
        //获取选中的购物车
        List<Map<String, Object>> cartList = webPortalClient.findNewOrderItemList2(tbOrder.getUsername());
        List<TbOrderItem> collect = cartList.stream().filter(cart -> (boolean) cart.get("checked")).map(cart -> JSON.parseObject(JSON.toJSONString(cart.get("item")), TbOrderItem.class) ).collect(Collectors.toList());
       // JSON.parseObject(JSON.toJSONString(cart.get("item")), TbOrderItem.class);
        // 扣减库存
        boolean b = goodsClient.deductionStock(collect);
        if(!b){
            throw new GuliException(20001,"库存不足");
        }

        try {
            // 保存订单主表
            tbOrder.setId(idWorker.nextId()+"");
            IntStream intStream = collect.stream().mapToInt(TbOrderItem::getNum);
            int sum = intStream.sum();
            IntStream intStream2 = collect.stream().mapToInt(TbOrderItem::getMoney);
            int money = intStream2.sum();
            int i = webPortalClient.preferential2(tbOrder.getUsername());
            tbOrder.setTotalMoney(money);
            tbOrder.setTotalNum(sum);
            tbOrder.setPreMoney(i); //优惠金额
            tbOrder.setPayMoney(tbOrder.getTotalMoney()-tbOrder.getPreMoney());
            tbOrder.setCreateTime(new Date());
            tbOrder.setOrderStatus("0"); // 订单状态
            tbOrder.setPayStatus("0");// 支付状态
            tbOrder.setConsignStatus("0");// 发货状态
            tbOrder.setSourceType("1");
            tbOrder.setPostFee(sum*80); //邮费
            tbOrder.setIsDelete("0");
            tbOrderMapper.insert(tbOrder);
            // 保存订单明细表
            // 打折比例
            double proportion= (double) tbOrder.getPayMoney()/tbOrder.getTotalMoney();

            for (TbOrderItem orderItem:collect){
                orderItem.setId(idWorker.nextId()+"");
                orderItem.setOrderId(tbOrder.getId());
                orderItem.setPostFee(80);
                orderItem.setPayMoney((int)(orderItem.getMoney()*proportion));
                tbOrderItemMapper.insert(orderItem);

            }
        } catch (Exception e) {
            e.printStackTrace();
            for (TbOrderItem orderItem:collect){
                orderItem.setOrderId(tbOrder.getId());
            }
            amqpTemplate.convertAndSend("queue.skuback",collect);
            throw new GuliException(20001,"创建订单失败");
        }
        // 清除购物车
        webPortalClient.deleteCheckedCart2(tbOrder.getUsername());

        // 发送延迟消息 60分钟后查询订单状态
        amqpTemplate.convertAndSend("quque.order",tbOrder.getId());
        // 返回map
        Map<String,Object> map=new HashMap<>();
        map.put("ordersn",tbOrder.getId());
        map.put("money",tbOrder.getPayMoney());
        return map;
    }

    @Override
    public void updatePayStatus(String orderId, String transaction) {
        TbOrder order = tbOrderMapper.selectByPrimaryKey(orderId);
        if(order!=null && "0".equals(order.getPayStatus())){
            order.setTransactionId(transaction);// 交易流水号
            order.setPayStatus("1"); // 支付状态
            order.setOrderStatus("1");// 订单状态
            order.setUpdateTime(new Date());// 修改日期
            order.setPayTime(new Date());// 支付日期

            tbOrderMapper.updateByPrimaryKeySelective(order);
            // 记录订单日志
            addLog(order,"交易流水号:"+transaction);
        }


    }

    @Override
    public void okOrder(String id) {
        TbOrder order = new TbOrder();
        order.setId(id);
        order.setOrderStatus("3");
        tbOrderMapper.updateByPrimaryKeySelective(order);
    }

    @Override
    public PageUtil<OrderItemSku> queryOrderItemSkuByUsername(String username, Integer pageNum, Integer pageSize,Integer orderStatus) {
        List<OrderItemSku> orderItemSkus = new ArrayList<>();
        if (orderStatus == 5) {
            PageHelper.startPage(pageNum, pageSize);
            orderItemSkus = tbOrderMapper.queryOrderItemSkuByUsernameAll(username, orderStatus);
        } else {
            PageHelper.startPage(pageNum, pageSize);
            orderItemSkus = tbOrderMapper.queryOrderItemSkuByUsername(username,orderStatus);
        }
        PageInfo<OrderItemSku> pageInfo = new PageInfo(orderItemSkus);
        return new PageUtil<OrderItemSku>(pageInfo.getTotal(), pageInfo.getList());
    }

    @Override
    public OrderItemSku queryOrderItemSkuByOrderId(String id) {
        OrderItemSku orderItemSku = tbOrderMapper.queryOrderItemSkuByOrderId(id);
        return orderItemSku;
    }

    @Autowired
    private WxPayService wxPayService;

    @RabbitListener(queues = "queue.ordertimeout")
    public void listenerOrder(String orderId){
        TbOrder order = tbOrderMapper.selectByPrimaryKey(orderId);
        if("0".equals(order.getOrderStatus()) || "0".equals(order.getPayStatus())){
             // 未支付
            // 再次到微信平台确认订单是否支付
            wxPayService.selectOrder(orderId);
        }
    }

    @RabbitListener(queues = "queue.ordersj")
    public void listenerOrderOutTime(TbOrderConfig tbOrderConfig){

        RabbitConfig.outTime=tbOrderConfig.getOrderTimeout()*60*1000;
    }

}
